""" Parameter dictionaries.

Here, we store various parameter dictionaries with "sensible" (typically unitary or
zero) default values for the parameters required by the discretization objects.
"""

from __future__ import annotations

import numpy as np

import porepy as pp


def flow_dictionary(g, in_data=None):
    """Dictionary with parameters for standard flow problems.

    All parameters listed below which are not specified in in_data are assigned default
    values. Additional parameters may be passed in in_data.

    Args:
        g: Grid.
        in_data: Dictionary containing any custom (non-default) parameter values.

    Returns:
        Dictionary with the "mathematical" parameters required by various flow
            discretization objects specified.
    """
    # Ensure that the standard flow parameters are present in d. Values from in_data
    # have priority over the default values.
    d = {
        "source": np.zeros(g.num_cells),
        "mass_weight": np.ones(g.num_cells),
        "second_order_tensor": pp.SecondOrderTensor(np.ones(g.num_cells)),
        "bc": pp.BoundaryCondition(g),
        "bc_values": np.zeros(g.num_faces),
        "time_step": 1,
    }

    # Ensure that parameters not handled above are copied. Values from in_data have
    # priority over the default values.
    if not in_data:
        in_data = {}
    d.update(in_data)
    return d


def transport_dictionary(g, in_data=None):
    """Dictionary with parameters for standard transport problems.

    All parameters listed below which are not specified in in_data are assigned default
    values. Additional parameters may be passed in in_data.

    Args:
        g: Grid.
        in_data: Dictionary containing any custom (non-default) parameter values.

    Returns:
        Dictionary with the "mathematical" parameters required by various flow
            discretization objects specified.
    """
    # Ensure that the standard transport parameters are present in d. Values from
    # in_data have priority over the default values.
    d = {
        "source": np.zeros(g.num_cells),
        "mass_weight": np.ones(g.num_cells),
        "second_order_tensor": pp.SecondOrderTensor(np.ones(g.num_cells)),
        "bc": pp.BoundaryCondition(g),
        "bc_values": np.zeros(g.num_faces),
        "darcy_flux": np.zeros(g.num_faces),
        "time_step": 1,
    }

    # Ensure that parameters not handled above are copied. Values from in_data have
    # priority over the default values.
    if not in_data:
        in_data = {}
    d.update(in_data)
    return d


def mechanics_dictionary(g, in_data=None):
    """Dictionary with parameters for standard mechanics problems.

    All parameters listed below which are not specified in in_data are assigned default
    values. Additional parameters may be passed in in_data.

    Args:
        g: Grid.
        in_data: Dictionary containing any custom (non-default) parameter values.

    Returns:
        Dictionary with the "mathematical" parameters required by various flow
            discretization objects specified.
    """
    # Ensure that the standard mechanics parameters are present in d.
    d = {
        "porosity": np.ones(g.num_cells),
        "source": np.zeros(g.dim * g.num_cells),
        "mass_weight": np.ones(g.num_cells),
        "fourth_order_tensor": pp.FourthOrderTensor(
            np.ones(g.num_cells), np.ones(g.num_cells)
        ),
        "bc": pp.BoundaryConditionVectorial(g),
        "bc_values": np.zeros(g.dim * g.num_faces),
        "slip_distance": np.zeros(g.num_faces * g.dim),
        "time_step": 1,
    }

    # Ensure that parameters not handled above are copied. Values from in_data have
    # priority over the default values.
    if not in_data:
        in_data = {}
    d.update(in_data)
    return d
